﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace ToodledoAPI
{
    /// <summary>
    /// This static class stores the only state in the library
    /// It is important to begin by setting the configuration before calling any other methods in the API
    /// </summary>
    public static class ApplicationConfiguration
    {
        static IApplicationConfiguration configuration;
        static IDeviceSpecification deviceSpecification;
        /// <summary>
        /// Set the configuration (Should be called before calling any other methods)
        /// </summary>
        /// <param name="Configuration">A class sumarising the configuration of the application</param>
        /// <param name="DeviceSpecification">An optional class describing this device, can be used as you wish and is logged on toodledo's server when you login.</param>
        public static void SetConfiguration(IApplicationConfiguration Configuration, IDeviceSpecification DeviceSpecification = null)
        {
            Initialized = true;
            configuration = Configuration;
            deviceSpecification = DeviceSpecification;
        }

        /// <summary>
        /// Resets the configuration to null, shouldn't be needed unless you wish to free up memory used by your configuration
        /// </summary>
        [Obsolete]
        public static void ClearConfiguration()
        {
            Initialized = false;
            configuration = null;
            deviceSpecification = null;
        }
        /// <summary>
        /// Inisialized allows us to ensure the appsettings are initialized and throw an exception if anything is requested and they aren't
        /// </summary>
        static bool Initialized = false;

        internal static string AppID
        {
            get
            {
                if (!Initialized)
                    throw new ApplicationConfigurationNotSetException();
                return configuration.AppID;
            }
        }
        internal static string AppToken
        {
            get
            {
                if (!Initialized)
                    throw new ApplicationConfigurationNotSetException(); 
                return configuration.AppToken;
            }
        }

        static IRestWebServiceProxy ProxyService { get { return configuration.ProxyService; } }

        internal static TaskDetailsConfiguration taskDetailsConfiguration
        {
            get
            {
                if (!Initialized)
                    throw new ApplicationConfigurationNotSetException(); 
                return configuration.TaskDetailsConfiguration;
            }
        }
        internal static IDeviceSpecification DeviceSpecification
        {
            get
            {
                if (!Initialized)
                    throw new ApplicationConfigurationNotSetException(); 
                return deviceSpecification;
            }
        }

        internal static void CallWebService(string Method, Action<string> returnStatement)
        {
            if (!Initialized)
                throw new ApplicationConfigurationNotSetException();
            if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
                throw new NoInternetConnectionException();

            ProxyService.CallWebService("http://api.toodledo.com/2/" + Method, returnStatement);
        }
    }

    public class NoInternetConnectionException:Exception
    {
        public override string Message
        {
            get
            {
                return "You can't call the toodledo api without a network connection";
            }
        }
    }
    public class ApplicationConfigurationNotSetException:Exception
    {
        public override string Message
        {
            get
            {
                return "The application configuration has not been set.\n"+
                    "You must provide an AppID and AppToken after registering your applicaiton with Toodledo\n" +
                    "http://api.toodledo.com/2/account/doc_register.php\n" +
                    "Silverlight also requires a proxy since Toodledo does not have a suitable clientaccesspolicy file.\n" +
                    "You must therefore supply a class implimenting IRestWebServiceProxy.\n" +
                    "All these must be provided by a call to ApplicationConfiguration.SetConfiguration before calling any other api methods.";
            }
        }
    }


    public interface IRestWebServiceProxy
    {
        void CallWebService(string Method, Action<string> returnStatement);
    }

    /// <summary>
    /// Specifies the applicaiton configuration
    /// </summary>
    public interface IApplicationConfiguration
    {
        string AppID { get; }
        string AppToken { get; }
        /// <summary>
        /// Called once for each proxy service required.
        /// This allows you to choose between one instance handling all calls, or an instance per call.
        /// </summary>
        IRestWebServiceProxy ProxyService { get; }
        TaskDetailsConfiguration TaskDetailsConfiguration { get; }
    }
    public interface IDeviceSpecification
    {
        int Version { get; }
        string Device { get; }
        int OS { get; }
    }
}
